<html>
<head><meta charset="utf-8"><title>Best practice for #[inline] in a public crate · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html">Best practice for #[inline] in a public crate</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="225395925"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225395925" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Colin Finck <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225395925">(Feb 06 2021 at 07:44)</a>:</h4>
<p>Hi all! I'm going to publish my first public crate soon and was wondering about the current best practices for using <code>#[inline]</code>.<br>
My crate implements a few iterators, with some calling inner iterators, some having optimized <code>count</code>, <code>last</code>, <code>nth</code>, <code>size_hint</code> functions, etc.<br>
This makes up a lot of short functions, which I hope to see inlined during release builds.</p>
<p>Is it still considered best practice to put <code>#[inline]</code> everywhere I see fit or can I rely on LLVM to do "the right thing" today, even for default (non-LTO) release builds?</p>
<p>And if this still needs manual work:<br>
Should I better add <code>#[inline]</code> to the short <code>next</code> function of the public iterator - or rather to the long <code>next</code> function of my crate-internal iterator that is called by the public iterator?</p>



<a name="225405582"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225405582" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225405582">(Feb 06 2021 at 11:26)</a>:</h4>
<p><code>#[inline]</code> is sometimes required for LLVM to be able to inline cross-crate calls at all without LTO. Only generic and <code>#[inline]</code> functions get the MIR encoded that is necessary to codegen LLVM ir in the target crate as necessary for LLVM to inline functions.</p>



<a name="225411571"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225411571" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225411571">(Feb 06 2021 at 13:20)</a>:</h4>
<p>inlining shorter functions is more likely going to lead to faster builds.</p>



<a name="225411595"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225411595" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225411595">(Feb 06 2021 at 13:21)</a>:</h4>
<p>IMO the rule of thumb would be to not <code>#[inline]</code> anything unless machine code inspection and/or benchmarks show an improvement in metrics you care about.</p>



<a name="225412811"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225412811" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Colin Finck <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225412811">(Feb 06 2021 at 13:48)</a>:</h4>
<p>@nagisa On the other hand, one can't really claim to provide zero-cost abstractions, when adding another layer of indirection that is surely not inlined away</p>



<a name="225418018"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225418018" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225418018">(Feb 06 2021 at 15:57)</a>:</h4>
<p>Just tell people to turn on thin LTO in release builds and never think about it again.</p>



<a name="225422123"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225422123" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225422123">(Feb 06 2021 at 17:36)</a>:</h4>
<p>I tend to inline things that are small, or where I expect it to have a meaningful difference for the optimizer (often constructors get inlined, iterator next impls, etc), but these take some time to develop intuition. I basically never use #[inline(always)].</p>



<a name="225422303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225422303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Colin Finck <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225422303">(Feb 06 2021 at 17:40)</a>:</h4>
<p>That means you also put an <code>#[inline]</code> around every trait impl? (e.g. <code>eq</code> of PartialEq or <code>partial_cmp</code> of PartialOrd are usually one-liners for me)</p>



<a name="225422666"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225422666" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Colin Finck <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225422666">(Feb 06 2021 at 17:48)</a>:</h4>
<p>I think I have some intuition where it would make sense to inline. It's just that it would be very tedious to add <code>#[inline]</code> to each and every short function, and I would assume LLVM to already do that for me at a moderate optimization level</p>



<a name="225422688"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225422688" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Colin Finck <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225422688">(Feb 06 2021 at 17:49)</a>:</h4>
<p>But looks like LLVM actually needs to be told considering what <span class="user-mention" data-user-id="133247">@bjorn3</span> says</p>



<a name="225422866"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225422866" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225422866">(Feb 06 2021 at 17:53)</a>:</h4>
<p>The problem is in rustc, not LLVM here. <a href="https://github.com/rust-lang/rust/issues/78120">https://github.com/rust-lang/rust/issues/78120</a> could fix having to put <code>#[inline]</code> on everything.</p>



<a name="225429233"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225429233" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225429233">(Feb 06 2021 at 20:40)</a>:</h4>
<p><span class="user-mention silent" data-user-id="350190">Colin Finck</span> <a href="#narrow/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate/near/225422666">said</a>:</p>
<blockquote>
<p>I think I have some intuition where it would make sense to inline. It's just that it would be very tedious to add <code>#[inline]</code> to each and every short function, and I would assume LLVM to already do that for me at a moderate optimization level</p>
</blockquote>
<p>LLVM will always inline small-enough functions when optimizing -- even when size optimizing -- when the definition is available to it (and it's not marked <code>inline(never)</code>).</p>



<a name="225436170"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225436170" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225436170">(Feb 06 2021 at 23:54)</a>:</h4>
<p>To add to what scott said: small, non-generic functions won't inline across crate bounds without <code>#[inline]</code>. Unfortunately, tagging every single such function is, indeed, exactly as boring as it sounds.</p>
<p>Which is why I suggested telling people to just activate thin LTO. It will allow cross-crate inlining in all code within the build.</p>



<a name="225436231"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225436231" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225436231">(Feb 06 2021 at 23:57)</a>:</h4>
<p>(And do so without the cargo-pipelining-blocking and other implications of having <code>[inline]</code> and thus forcing them to be emitted into MIR and CGU-repeated and such)</p>



<a name="225436328"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225436328" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Tyson Nottingham <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225436328">(Feb 07 2021 at 00:00)</a>:</h4>
<p>Do we currently repeat <code>#[inline]</code> functions in multiple CGUs even if LTO is enabled? Would it make sense to avoid doing that?</p>



<a name="225453266"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225453266" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Colin Finck <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225453266">(Feb 07 2021 at 08:53)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> Yeah, thinking more about that, I'll remove all #[inline]s and just refer people to ThinLTO now. After all, this is something a compiler should be able to do better than any human</p>



<a name="225453323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225453323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225453323">(Feb 07 2021 at 08:55)</a>:</h4>
<p>As someone who is myself the purveyor of thin glue crates full of hundreds of functions, you have my sympathies</p>



<a name="225463056"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Best%20practice%20for%20%23%5Binline%5D%20in%20a%20public%20crate/near/225463056" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate.html#225463056">(Feb 07 2021 at 12:59)</a>:</h4>
<p><span class="user-mention silent" data-user-id="350190">Colin Finck</span> <a href="#narrow/stream/122651-general/topic/Best.20practice.20for.20.23.5Binline.5D.20in.20a.20public.20crate/near/225422303">said</a>:</p>
<blockquote>
<p>That means you also put an <code>#[inline]</code> around every trait impl? (e.g. <code>eq</code> of PartialEq or <code>partial_cmp</code> of PartialOrd are usually one-liners for me)</p>
</blockquote>
<p>Often, sure. But small also generally means in terms of code size. I also dont generally inline if the implementation just calls another non-inline function. It's mostly about giving the compiler useful info to work with. I'd definitely go for partialeq/partialord tho if the types are small</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>